import os
import sys
import json
import subprocess
import tempfile
import threading
import winreg as reg
from datetime import datetime
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
import psutil
import re
from pathlib import Path
import subprocess

import os
import sys
from functools import lru_cache

__all__ = ["Resource_Path"]
@lru_cache(maxsize=None)
def Resource_Path(relative_path: str) -> str:
    """
    将相对路径解析为绝对路径。
    若 relative_path 已经是绝对路径，则直接返回。
    自动识别打包器并定位到正确的运行时目录。
    """
    if os.path.isabs(relative_path):
        return relative_path

    # 1. PyInstaller
    if hasattr(sys, "_MEIPASS"):
        base = sys._MEIPASS
        base = os.path.dirname(base)
        print("PyInstaller EXE阶段运行路径:"+base)
    else:
        base = os.path.dirname(os.path.abspath(__file__))
        print(".PY阶段运行路径:"+base)
    
    return os.path.normpath(os.path.join(base, relative_path))

subprocess.run(
    ['setx', 'PATH', Resource_Path("Ollama")],
    creationflags=subprocess.CREATE_NO_WINDOW
)
subprocess.run(
    ['setx', 'OLLAMA_HOST',"0.0.0.0:11434"],
    creationflags=subprocess.CREATE_NO_WINDOW
)
subprocess.run(
    ['setx', 'OLLAMA_ORIGINS', "http://localhost:11435"],
    creationflags=subprocess.CREATE_NO_WINDOW
)
subprocess.run(
    ['setx', 'OLLAMA_KEEP_ALIVE', "4"],
    creationflags=subprocess.CREATE_NO_WINDOW
)


# ----------------------------------------------------------------------
# 2. Ollama 进程封装
# ----------------------------------------------------------------------
class OllamaProcess(QObject):
    new_line = pyqtSignal(str)
    def __init__(self):
        super().__init__()
        self.proc = None
        
        
    def start(self):
        self.proc = QProcess()
        self.proc.setProgram("ollama.exe")
        self.proc.setArguments(["serve"])
        self.proc.setWorkingDirectory(Resource_Path("Ollama"))
        env = QProcessEnvironment.systemEnvironment()
        env.insert("OLLAMA_MODELS", Resource_Path("Ollama/Models"))
        print(Resource_Path("Ollama/Models"))
        self.proc.setProcessEnvironment(env)
        self.proc.setProcessChannelMode(QProcess.MergedChannels)
        self.proc.start()
        
    def stop(self):
        if self.proc and self.proc.state() != QProcess.NotRunning:
            self.proc.terminate()
            if not self.proc.waitForFinished(3000):  # 最多等待 3 秒
                self.proc.kill()  # 强制结束
                self.proc.waitForFinished(1000)

# ----------------------------------------------------------------------
# 5. 主托盘应用
# ----------------------------------------------------------------------
class TrayApp(QApplication):
    def __init__(self, argv):
        super().__init__(argv)
        self.setQuitOnLastWindowClosed(False)

        self.ollama = OllamaProcess()


        self.tray = QSystemTrayIcon(self)
        self.tray.setIcon(QIcon("Heart.ico"))
        self.tray.setVisible(True)

        self.menu = QMenu()
        self.start_action = QAction("启动 Ollama")
        self.stop_action = QAction("停止 Ollama")
        self.quit_action = QAction("退出")

        self.menu.addAction(self.start_action)
        self.menu.addAction(self.stop_action)
        self.menu.addSeparator()
        self.menu.addSeparator()
        self.menu.addAction(self.quit_action)

        self.tray.setContextMenu(self.menu)

        # 连接信号
        self.start_action.triggered.connect(self.start_ollama)
        self.stop_action.triggered.connect(self.stop_ollama)
        self.quit_action.triggered.connect(self.exit_app)

        self.hw_timer = QTimer(self)
        self.hw_timer.start(2000)
        self.start_ollama()

    def start_ollama(self):
        self.ollama.start()

    def stop_ollama(self):
        self.ollama.stop()


    def exit_app(self):
        self.ollama.stop()
        QApplication.processEvents()
        QApplication.quit()

# ----------------------------------------------------------------------
# 运行
# ----------------------------------------------------------------------
if __name__ == '__main__':
    app = TrayApp(sys.argv)
    sys.exit(app.exec_())
